//package com.hjh.netty.elect.demo2;
//
//import io.netty.buffer.ByteBuf;
//import io.netty.buffer.Unpooled;
//import io.netty.channel.Channel;
//import io.netty.channel.ChannelFutureListener;
//import io.netty.channel.ChannelHandlerContext;
//import io.netty.channel.ChannelInboundHandlerAdapter;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.PostConstruct;
//import javax.annotation.Resource;
//import java.nio.charset.StandardCharsets;
//import java.util.concurrent.TimeUnit;
//
//@Slf4j
//@Component
//public class NettyServerHandler extends ChannelInboundHandlerAdapter {
//
////    @Resource
////    private RedisUtil redisUtil;
//
//    private static NettyServerHandler nettyServerHandler;
//
//    /**
//     * redis key过期时间，单位是秒
//     */
//    private static final Integer EXPIRE_TIME = 90;
//
//    @PostConstruct
//    private void init() {
//        nettyServerHandler = this;
//    }
//
//    /**
//     * 写数据方法
//     *
//     * @param serial 序列号
//     * @param msg    数据（16进制字符串）
//     */
//    public void write(String serial, String msg) {
//        // 获取序列号对应的uid
//        String uid = (String) nettyServerHandler.redisUtil.get(KeyConfig.SERIAL_KEY_VALUE + serial);
//        if (uid != null) {
//            try {
//                Channel channel = ChannelMap.getTimeServerChannel(uid);
//                writeToClient(msg, channel);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        } else {
//            // TODO redis保存的channel已经过期，表示设备长时间未收到心跳，当离线处理
//            // 删除uid对应的key和序列号对应的key
//            nettyServerHandler.redisUtil.delete(KeyConfig.UID_KEY_VALUE + uid);
//            nettyServerHandler.redisUtil.delete(KeyConfig.SERIAL_KEY_EXPIRE + serial);
//            nettyServerHandler.redisUtil.delete(KeyConfig.SERIAL_KEY_VALUE + serial);
//        }
//    }
//
//    /**
//     * 公用回写数据到客户端的方法
//     *
//     * @param receiveStr
//     * @param channel
//     */
//    private void writeToClient(final String receiveStr, Channel channel) {
//        try {
//            // netty需要用ByteBuf传输
//            ByteBuf bufff = Unpooled.buffer();
//            // 对接需要16进制
//            bufff.writeBytes(ConvertCode.hexString2Bytes(receiveStr));
//            channel.writeAndFlush(bufff).addListener((ChannelFutureListener) future -> {
//                if (future.isSuccess()) {
//                    log.info("回写成功：" + receiveStr);
//                } else {
//                    log.info("回写失败：" + receiveStr);
//                }
//            });
//        } catch (Exception e) {
//            e.printStackTrace();
//            System.out.println("调用通用writeToClient()异常" + e.getMessage());
//        }
//    }
//
//    /**
//     * 客户端连接会触发
//     */
//    @Override
//    public void channelActive(ChannelHandlerContext ctx) {
//        log.info("客户端已连接到服务器：{}", ctx);
//        ctx.flush();
//    }
//
//    /**
//     * 客户端发消息会触发
//     */
//    @Override
//    public void channelRead(ChannelHandlerContext ctx, Object msg) {
//        ByteBuf buf = (ByteBuf) msg;
//        int length = buf.readableBytes();
//        byte[] bytes = new byte[length];
//        int i = 0;
//        while (i < length) {
//            bytes[i] = buf.readByte();
//            buf.markReaderIndex();
//            i++;
//        }
//        String str = new String(bytes, StandardCharsets.UTF_8);
//        if ("Q".equals(str)) {
//            // 处理心跳
//            log.info("服务器收到心跳: {}，客户端为：{}", str, ctx);
//            String uuid = ctx.channel().id().asLongText();
//            String serial = (String) nettyServerHandler.redisUtil.get(KeyConfig.UID_KEY_VALUE + uuid);
//            nettyServerHandler.redisUtil.setEx(KeyConfig.SERIAL_KEY_EXPIRE + serial, uuid, EXPIRE_TIME, TimeUnit.SECONDS);
//            // 回复字符串 A 防止设备自检测导致重连
//            ByteBuf buff = Unpooled.buffer();
//            ctx.writeAndFlush(buff.writeBytes("A".getBytes(StandardCharsets.UTF_8)));
//        } else if (str.indexOf("ZR") == 0) {
//            // 处理首次连接
//            String uuid = ctx.channel().id().asLongText();
//            log.info("设备首次连接，序列号为: {}，uuid为：{}，客户端为: {}", str, uuid, ctx);
//            // 保存通道
//            ChannelMap.addTimeServerChannel(uuid, ctx.channel());
//            // 冗余uid和序列号对应数据，方便过期删除
//            nettyServerHandler.redisUtil.setEx(KeyConfig.SERIAL_KEY_EXPIRE + str, uuid, EXPIRE_TIME, TimeUnit.SECONDS);
//            nettyServerHandler.redisUtil.set(KeyConfig.SERIAL_KEY_VALUE + str, uuid);
//            nettyServerHandler.redisUtil.set(KeyConfig.UID_KEY_VALUE + uuid, str);
//        } else {
//            // 处理响应消息
//            String s1 = ConvertCode.bytes2HexString(bytes);
//            //对接需要16进制
//            log.info("服务器收到消息: {}，客户端为：{}", s1, ctx);
//        }
//    }
//
//    /**
//     * 客户端主动断开服务端的连接会触发
//     */
//    @Override
//    public void channelInactive(ChannelHandlerContext ctx) {
//        log.info("客户端主动与服务器断开连接：{}", ctx);
//        String uuid = ctx.channel().id().asLongText();
//        ChannelMap.removeTimeServerChannel(uuid);
//        // 获取序列号
//        String serial = (String) nettyServerHandler.redisUtil.get(KeyConfig.UID_KEY_VALUE + uuid);
//        nettyServerHandler.redisUtil.delete(KeyConfig.SERIAL_KEY_VALUE + serial);
//        nettyServerHandler.redisUtil.delete(KeyConfig.SERIAL_KEY_EXPIRE + serial);
//        nettyServerHandler.redisUtil.delete(KeyConfig.UID_KEY_VALUE + uuid);
//    }
//
//    /**
//     * 发生异常触发
//     */
//    @Override
//    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
//        // 打印异常
//        cause.printStackTrace();
//        //关闭Channel
//        ctx.close();
//    }
//
//}
